package org.bob.learn.web.controller;

import lombok.extern.slf4j.Slf4j;
import org.bob.learn.common.util.JacksonUtils;
import org.bob.learn.service.FileService;
import org.bob.learn.web.model.Result;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/**
 * 文件相关控制器
 * 文件路径控制策略：
 * 由控制器统一控制: 接口固定路径前缀+接口动态入参相对路径
 */
@Slf4j
@RestController
@RequestMapping("/file")
public class FileController {

    private final static String UPLOAD_PATH = "/apprun/logs/dpyy-data-platform/";

    private final static String DOWNLOAD_PATH = "/apprun/logs/dpyy-data-platform/";

    private final FileService fileService;

    public FileController(FileService fileService) {
        this.fileService = fileService;
    }

    @PostMapping(value="/upload",produces = MediaType.MULTIPART_FORM_DATA_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono<Void> upload(@RequestPart("file") FilePart file, ServerHttpResponse response) {
        return fileService.save(UPLOAD_PATH,file).flatMap(stringResult -> {
                response.setStatusCode(HttpStatus.OK);
                DataBufferFactory bufferFactory = new DefaultDataBufferFactory();
                DataBuffer buffer = bufferFactory.wrap(JacksonUtils.toJson(stringResult).getBytes());
                response.getHeaders().setContentType(MediaType.TEXT_PLAIN);
                return response.writeWith(Mono.just(buffer));
        });
    }

    @GetMapping("/download/{fileName}")
    public Mono<ResponseEntity<Resource>> download(@PathVariable String fileName) {
        return fileService.read(DOWNLOAD_PATH+fileName).map(fileResult -> {
            if (fileResult.isSuccess()) {
                Resource resource =new FileSystemResource(fileResult.getData());
                return ResponseEntity.ok()
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileResult.getData().getName() + "\"")
                        .contentType(MediaType.APPLICATION_OCTET_STREAM)
                        .contentLength(fileResult.getData().length())
                        .body(resource);
            }else {
                return ResponseEntity.status(404).contentType(MediaType.APPLICATION_JSON).build();
            }
        });
    }
}
